/*-------------------------------------------------------------------------
 - Copyright (c) 2024-2025 [XD-AMCC TEAM]
 - [XD-AMCC] is licensed under Mulan PSL v2.
 - You can use this software according to the terms and conditions of the Mulan PSL v2.
 - You may obtain a copy of Mulan PSL v2 at:
 -          http://license.coscl.org.cn/MulanPSL2
 - THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES
 - OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 - TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 - See the Mulan PSL v2 for more details.
 ------------------------------------------------------------------------*/


/**
 * @brief Implement the API of class symbol entry.
 *
 *
 * @author  WXQ#XDU
 * @date    2024.12
 */


#include "inside/_stb_inner.h"


t_tree_ptr symentry_treenode (t_symentry_ptr pThis) {
    return (NULL == pThis) ? NULL : pThis->definitionTreeNode;
}

bool symentry_is_scalar (t_symentry_ptr pThis) {
    return type_is_scalar(symentry_type(pThis));
}

bool symentry_is_array (t_symentry_ptr pThis) {
    return type_is_array(symentry_type(pThis));
}

bool symentry_is_func (t_symentry_ptr pThis) {
    return tree_is_funcNameDefinition(pThis->definitionTreeNode);
}

bool symentry_is_label (t_symentry_ptr pThis) {
    return tree_is_labelNameDefinition(pThis->definitionTreeNode);
}


t_func_symInfo_ptr symentry_func_info (t_symentry_ptr pThis) {
    if (NULL == pThis) return NULL ;
    if (tree_is_funcNameDefinition(pThis->definitionTreeNode))
        return  pThis->content.funcInfo;

    return NULL;
}


t_symtable_ptr symentry_func_symtable (t_symentry_ptr pThis) {
    if (NULL == pThis) return NULL ;
    if (tree_is_funcNameDefinition(pThis->definitionTreeNode)) {
        return pThis->content.funcInfo->symTablePtr;
    }

    return NULL;
}


t_type_ptr symentry_func_returntype (t_symentry_ptr pThis) {
    if (NULL != pThis &&
        tree_is_funcNameDefinition(pThis->definitionTreeNode))
    {
        return type_func_return(pThis->content.funcInfo->typePtr);
    }

    return  NULL;
}


t_list_ptr symentry_func_params (t_symentry_ptr pThis) {
    if (NULL != pThis &&
        tree_is_funcNameDefinition(pThis->definitionTreeNode))
    {
        return &(pThis->content.funcInfo->parameterList);
    }

    return NULL;
}


t_label_symInfo_ptr symentry_label_info (t_symentry_ptr pThis) {
    if (NULL == pThis) return NULL ;
    if (tree_is_labelNameDefinition(pThis->definitionTreeNode))
        return  pThis->content.labelInfo;

    return NULL;
}


t_tree_ptr symentry_label_parent (t_symentry_ptr pThis) {
    if (NULL == pThis) return NULL ;
    if (tree_is_labelNameDefinition(pThis->definitionTreeNode))
        return  pThis->content.labelInfo->labeledStatementNode;

    return NULL;
}



t_var_symInfo_ptr symentry_var_info (t_symentry_ptr pThis) {
    if (NULL == pThis) return NULL ;
    if (tree_is_varNameDefinition(pThis->definitionTreeNode))
        return  pThis->content.varInfo;

    return NULL;
}


int  symentry_var_dimcount (t_symentry_ptr pThis) {
    return type_var_dimcount(symentry_type(pThis));
}


int  symentry_var_arraylimit (t_symentry_ptr pThis, int k) {
    return type_var_dimlength(symentry_type(pThis), k);
}


size_t symentry_var_offset (t_symentry_ptr pThis) {
    t_var_symInfo_ptr pVarInfo = symentry_var_info(pThis);
    return (NULL == pVarInfo) ? 0 : pVarInfo->offset;
}


size_t symentry_var_size (t_symentry_ptr pThis) {
    t_type_ptr typePtr = symentry_type(pThis);
    return (NULL == typePtr) ? 0 : type_width(typePtr);
}


t_tree_ptr symentry_var_initializer (t_symentry_ptr pThis) {
    t_var_symInfo_ptr pVarInfo = symentry_var_info(pThis);
    return (NULL == pVarInfo) ? NULL : pVarInfo->initializerNode;
}

t_list_ptr symentry_array_initExprs(t_symentry_ptr pThis) {
    t_var_symInfo_ptr pVarInfo = symentry_var_info(pThis);
    return (NULL == pVarInfo) ? NULL : pVarInfo->initExprs;
}

t_type_ptr symentry_type (t_symentry_ptr pThis) {
    if (NULL == pThis) return NULL;
    if (tree_is_funcNameDefinition(pThis->definitionTreeNode) ) {
        return (pThis->content.funcInfo->typePtr);
    }
    else if (tree_is_varNameDefinition(pThis->definitionTreeNode)) {
        return (pThis->content.varInfo->typePtr);
    }

    return NULL;
}

const char * symentry_typename (t_symentry_ptr pThis) {
    if (NULL == pThis)
        return "";

    if (tree_is_funcNameDefinition(pThis->definitionTreeNode) ) {
        return type_name(pThis->content.funcInfo->typePtr);
    }
    else if (tree_is_varNameDefinition(pThis->definitionTreeNode)) {
        return type_name(pThis->content.varInfo->typePtr);
    }

    return "LABEL";
}
